package com.io.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * Created by 41579 on 2016/12/23.
 */
public class NIOServer1 {
    //通道管理器
    private Selector selector;

    public static void main(String[] args) throws IOException {
        new NIOServer1().init(9981).listen();
    }

    //获取一个ServerSocket通道，并初始化通道
    public NIOServer1 init(int port) throws IOException {
        //获取一个ServerSocket通道
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);
        serverChannel.socket().bind(new InetSocketAddress(port));
        //获取通道管理器
        selector = Selector.open();
        //将通道管理器与通道绑定，并为该通道注册SelectionKey.OP_ACCEPT事件，
        //只有当该事件到达时，Selector.select()会返回，否则一直阻塞。
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        return this;
    }

    public void listen() throws IOException {
        System.out.println("服务器端启动成功");

        //使用轮询访问selector
        while (true) {
            //当有注册的事件到达时，方法返回，否则阻塞。
            System.out.println("有注册事件到来" + selector.select());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //获取selector中的迭代器，选中项为注册的事件
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            System.out.println("有这么多个key:"+selectionKeys.size());
            Iterator<SelectionKey> ite = selectionKeys.iterator();
            while (ite.hasNext()) {
//                System.out.println("抿注册事件");
                SelectionKey key = ite.next();
//                //删除已选key，防止重复处理
//                ite.remove();
//                //客户端请求连接事件
//                if (key.isAcceptable()) {
//                    System.out.println("客户端请求连接事件");
//                    ServerSocketChannel server = (ServerSocketChannel) key.channel();
////                    //获得客户端连接通道
//                    SocketChannel channel = server.accept();
////                    channel.configureBlocking(false);
////                    channel.register(selector, SelectionKey.OP_READ);
////                    while(true) {
////                        int i = selector.select();
////                        if(i>0){
////                            continue;
////                        }
////                        Set<SelectionKey> selectionKeys = selector.selectedKeys();
////                        Iterator<SelectionKey> it = selectionKeys.iterator();
////                        while(it.hasNext()){
////                            SelectionKey key1 = it.next();
////                            it.remove();
////                            if(key1.isReadable()){
////                                System.out.println("read....");
////                            }
////                        }
////                    }
//
////                    channel.configureBlocking(false);
////                    //向客户端发消息
////                    channel.write(ByteBuffer.wrap(new String("send message to client").getBytes()));
////                    //在与客户端连接成功后，为客户端通道注册SelectionKey.OP_READ事件。
////                    channel.register(selector, SelectionKey.OP_READ);
//                } else if (key.isReadable()) {//有可读数据事件
//                    //获取客户端传输数据可读取消息通道。
//                    SocketChannel channel = (SocketChannel) key.channel();
//                    //创建读取数据缓冲器
//                    ByteBuffer buffer = ByteBuffer.allocate(10);
//                    int read = channel.read(buffer);
////                    byte[] data = buffer.array();
////                    String message = new String(data);
//
////                    System.out.println("receive message from client, size:" + buffer.position() + " msg: " + message);
//                    System.out.println("read...");
////                    ByteBuffer outbuffer = ByteBuffer.wrap(("server.".concat(msg)).getBytes());
////                    channel.write(outbuffer);
//                }
            }
        }
    }
}
